﻿using System;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Text;
using System.Web.Mvc;
using System.Web.Security;
using CultuRAM.DAL;
using CultuRAM.Filters;
using CultuRAM.Models;
using Twilio;
using WebMatrix.WebData;

namespace CultuRAM.Controllers
{
    [Authorize]
    [InitializeSimpleMembership]
    public class HomeController : Controller
    {
        private UnitOfWork _unitOfWork = new UnitOfWork();
        private ValidateLogin vLogin = new ValidateLogin();
       
        [AllowAnonymous]
        public ActionResult Index()
        {
            //ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";

            //var eventsHl = _unitOfWork.EventRepository.Get()
            //        .Where(x=> x.HasPropertyNullOrEqual("Destaque", "Sim") && x.StartDate >= DateTime.Now)
            //        .ToList().OrderBy(x => x.StartDate);

            var eventsHl = _unitOfWork.EventRepository.Get()
                                .Where(x=> x.HasPropertyNullOrEqual("Destaque", "Sim"))
                                .ToList().OrderBy(o => o.StartDate);
            
            //var nextEvents = _unitOfWork.EventRepository.Get()
            //        .Where(x => x.StartDate >= DateTime.Now)
            //        .ToList().OrderBy(x => x.StartDate);

            var nextEvents = _unitOfWork.EventRepository.Get()
                                .Where(x => x.StartDate >= DateTime.Now)
                                .ToList().OrderBy(o => o.StartDate);

            ViewBag.RoleId = GetRoleId();
            ViewBag.UserName = vLogin.ValLogin();

            return View(nextEvents);
        }

        [AllowAnonymous]
        public ActionResult About()
        {
            //ViewBag.Message = "Your app description page.";

            ViewBag.RoleId = GetRoleId();
            ViewBag.UserName = vLogin.ValLogin();

            return View();
        }

        [AllowAnonymous]
        public ActionResult Contact()
        {
            ViewBag.Message = "";

            ViewBag.RoleId = GetRoleId();
            ViewBag.UserName = vLogin.ValLogin();

            return View();
        }

        public ActionResult Dashboard()
        {
            ViewBag.RoleId = GetRoleId();
            ViewBag.UserName = vLogin.ValLogin();

            var dashboard = new Dashboard()
                {
                    AlertList = _unitOfWork.AlertRepository.Get(f => f.Active == true).OrderByDescending(o => o.Date).ToList(),
                    CommentList = _unitOfWork.CommentRepository.Get().ToList().Where(f => f.Date >= DateTime.Now.AddDays(-999)).OrderByDescending(o => o.Date).ToList(),
                    AccReqList = _unitOfWork.AccResquestRepository.Get(f => f.AccStateId == 1).OrderByDescending(o => o.RequestDate).ToList()
                };

            return View(dashboard);
        }

        public ActionResult DashboardEN()
        {
            ViewBag.RoleId = GetRoleId();
            ViewBag.UserName = vLogin.ValLogin();

            var dashboard = new Dashboard()
            {
                AlertList = _unitOfWork.AlertRepository.Get(f => f.Active == true).OrderByDescending(o => o.Date).ToList(),
                CommentList = _unitOfWork.CommentRepository.Get().ToList().Where(f => f.Date >= DateTime.Now.AddDays(-999)).OrderByDescending(o => o.Date).ToList(),
                AccReqList = _unitOfWork.AccResquestRepository.Get(f => f.AccStateId == 1).OrderByDescending(o => o.RequestDate).ToList()
            };

            return View(dashboard);
        }

        //
        // GET: /Entity/Create
        [AllowAnonymous]
        public ActionResult AccRequest()
        {
            PopulateCityDropDownList();
            PopulateEntityTypeDropDownList();
            ViewBag.RoleId = GetRoleId();
            ViewBag.UserName = vLogin.ValLogin();

            return View();
        }

        //
        // POST: /Entity/Create

        [HttpPost]
        [AllowAnonymous]
        public ActionResult AccRequest(Entity entity)
        {
            if (ModelState.IsValid)
            {
                _unitOfWork.EntityRepository.Insert(entity);
                _unitOfWork.Save();

                var codNum = 1;
                if (_unitOfWork.AccResquestRepository.GetList().Count != 0)
                {
                    codNum = _unitOfWork.AccResquestRepository.GetList().Last().AccReqId + 1;
                }

                var reqCode = CreateReqCode(5) + codNum;
                var senha = CreateReqCode(6);

                if (WebSecurity.UserExists(entity.Email))
                {
                    PopulateCityDropDownList(entity.CityId);
                    PopulateEntityTypeDropDownList(entity.EntityTypeId);
                    ViewBag.MsgError = "Já existe um utilizador com este email!";
                    return View(entity);
                }

                var vvv1 = _unitOfWork.UserProfileRepository.Get();
                WebSecurity.CreateUserAndAccount(entity.Email, senha, new { UserName = entity.Responsible, EntityId = entity.EntityId });
                Roles.AddUsersToRoles(new[] { entity.Email }, new[] { "Administrador" });
                _unitOfWork.Save();

                var vvv2 = _unitOfWork.UserProfileRepository.Get();


                //Accreditation Request Registration
                var accReq = new AccreditingRequest()
                    {
                        RequestCode = reqCode,
                        RequestDate = DateTime.Now,
                        FeedbackDate = DateTime.Now,
                        AccreditingState = _unitOfWork.AccStateRepository.GetByID(1),
                        Entity = _unitOfWork.EntityRepository.GetByID(entity.EntityId),
                        UserId = _unitOfWork.UserProfileRepository.GetList().LastOrDefault().UserId
                    };

                _unitOfWork.AccResquestRepository.Insert(accReq);
                _unitOfWork.Save();


                var urlBase = "http://" + Request.Url.Authority + Request.Url.Segments[0];
                urlBase = urlBase.Remove(urlBase.Length - 1);

                //Send EMAIL
                var fromEmail = "CultuRAM <verc04@gmail.com>";
                var toEmail = accReq.Entity.Email;
                var subjectString = "Pedido de Adesão";
                var bodyString = "Ex.mo(a) Sr.(a)<br>" +
                                 "<b>" + accReq.Entity.Responsible + "</b><br><br> " +
                                 "O pedido de adesão da entidade '<b>" + accReq.Entity.Name + "</b>' " +
                                 "na agenda de eventos CultuRAM foi registado com Sucesso! <br>" +
                                 "O seu pedido será sujeito a análise e em breve receberá a resposta via e-mail e " +
                                 "SMS caso tenha introduzido um número de telemóvel.<br><br>" +
                                 "Código do Pedido de Adesão: <b><a href='" + 
                                 urlBase + Url.Action("AccStatus", "Home", new { code = accReq.RequestCode }) + "'>" +
                                 accReq.RequestCode + "</a></b> (Utilize este código para consultar o estado do seu pedido.) <br><br>" +
                                 "As credênciais de acesso são as seguintes: <br>" +
                                 "Email: <b>" + entity.Email + "</b><br>" +
                                 "Palavra-passe: <b>" + senha + "</b><br><br>" +
                                 "<a href='" + urlBase + Url.Action("Auth", "Home") + "'> ENTRAR AGORA </a> <br><br>" +
                                 "Com os melhores cumprimentos, <br>Administração da CultuRAM";

                if (!String.IsNullOrEmpty(accReq.Entity.Email))
                    SendEmail(fromEmail, toEmail, subjectString, bodyString, accReq);


                //Send SMS
                var phoneTo = "+351" + entity.CellPhone;
                var smsString = "O pedido de adesão da entidade " + accReq.Entity.Name +
                                " na agenda de eventos CultuRAM foi registado com Sucesso! " +
                                "Código: " + accReq.RequestCode + " (Utilize este código para consultar o estado do seu pedido.)";
                if (!String.IsNullOrEmpty(entity.CellPhone))
                    SendSms(phoneTo, smsString);

                return RedirectToAction("AccReplay", "Home", new { @id = accReq.AccReqId });
            }

            PopulateCityDropDownList(entity.CityId);
            PopulateEntityTypeDropDownList(entity.EntityTypeId);
            return View(entity);
        }

        //
        // GET: /Entity/AccReplay
        [AllowAnonymous]
        public ActionResult AccReplay(int id)
        {
            var accReq = _unitOfWork.AccResquestRepository.GetByID(id);
            accReq.Entity = _unitOfWork.EntityRepository.GetByID(accReq.EntityId);

            ViewBag.RoleId = GetRoleId();
            ViewBag.UserName = vLogin.ValLogin();
            return View(accReq);
        }

        //
        // GET: /Entity/AccStatus
        [AllowAnonymous]
        public ActionResult AccStatus(string code)
        {
            var accReqTemp = _unitOfWork.AccResquestRepository.Get(filter: x => x.RequestCode.Equals(code)).FirstOrDefault();
            if (accReqTemp != null)
            {
                accReqTemp.Entity = _unitOfWork.EntityRepository.GetByID(accReqTemp.EntityId);
                //accReqTemp.AccreditingState = _unitOfWork.AccStateRepository.GetByID(1);

                ViewBag.RoleId = GetRoleId();
                ViewBag.UserName = vLogin.ValLogin();
                return View(accReqTemp);
            }
            //return RedirectToAction("Index","Home");

            ViewBag.RoleId = GetRoleId();
            ViewBag.UserName = vLogin.ValLogin();
            return View();
        }

        [AllowAnonymous]
        public ActionResult Auth(string error)
        {
            var lm = new LoginModel();

            if (Session["MsgError"] != null)
            {
                ViewBag.LoginError = Session["MsgError"].ToString();
                Session["MsgError"] = null;
            }

            //ViewBag.LoginError = error;

            return View(lm);
        }

        [AllowAnonymous]
        public ActionResult Faq()
        {
            ViewBag.RoleId = GetRoleId();
            ViewBag.UserName = vLogin.ValLogin();

            return View();
        }


        //AUXILIARY METHODS /////////////////////////////////////////////////////////


        //Method: Populate the DropDownList of Entity Type
        private void PopulateEntityTypeDropDownList(int? selectedEntityTypeId = 0)
        {
            if (selectedEntityTypeId == null)
            {
                var entityTypes = _unitOfWork.EntityTypeRepository.Get().ToList();
                ViewBag.EntityTypeId = new SelectList(entityTypes, "EntityTypeId", "EntityTypeName");
            }
            else
            {
                var entityTypes = _unitOfWork.EntityTypeRepository.Get().ToList();
                ViewBag.EntityTypeId = new SelectList(entityTypes, "EntityTypeId", "EntityTypeName", selectedEntityTypeId);
            }
        }

        //Method: Populate the DropDownList of City
        private void PopulateCityDropDownList(int? selectedCityId = 0)
        {
            if (selectedCityId == null)
            {
                var cities = _unitOfWork.CityRepository.Get().ToList();
                ViewBag.CityId = new SelectList(cities, "CityId", "CityName");
            }
            else
            {
                var cities = _unitOfWork.CityRepository.Get().ToList();
                ViewBag.CityId = new SelectList(cities, "CityId", "CityName", selectedCityId);
            }
        }

        //Method: Get Role ID
        private int GetRoleId()
        {
            var up = _unitOfWork.UserProfileRepository.GetByID(WebSecurity.CurrentUserId);
            if (up != null)
            {
                var roleName = Roles.GetRolesForUser(up.Email);

                return (from r in _unitOfWork.RolesRepository.GetList()
                        where r.RoleName.Equals(roleName[0])
                        select r.RoleId).FirstOrDefault();
            }

            return 0;
        }

        //Generate Code of the Accrediting Request
        public string CreateReqCode(int size)
        {
            const string caracteresValidos = "abcdefghijklmnopqrstuvwxyz";
            int maxValue = caracteresValidos.Length;
            Random random = new Random(DateTime.Now.Millisecond);
            StringBuilder code = new StringBuilder(size);

            for (int indice = 0; indice < size; indice++)
                code.Append(caracteresValidos[random.Next(0, maxValue)]);

            return code.ToString().ToUpper();
        }

        //Send Email Menssage
        public String SendEmail(string from, string to, string subject, string body, AccreditingRequest accReq)
        {

            var mail = new MailMessage(from, to);
            var smtp = new SmtpClient();
            String msg;

            try
            {
                mail.Subject = subject;
                mail.Body = body;
                mail.IsBodyHtml = true;
                mail.From = new MailAddress(from);
                //m.To.Add(new MailAddress(To));

                smtp.Host = "smtp.gmail.com";   // We use gmail as our smtp client
                smtp.Port = 587;
                smtp.EnableSsl = true;
                smtp.UseDefaultCredentials = true;
                smtp.Credentials = new NetworkCredential("geral.culturam@gmail.com", "cultur@m");
                smtp.Send(mail);

                msg = "Successful";

            }
            catch (Exception)
            {
                msg = "Error";
            }

            return msg;
        }

        //Send Email Menssage
        public bool SendSms(string phoneTo, string smsString)
        {

            const string accountSid = "AC9486809b7220f77eb74bc8bc0b05cae6";
            const string authToken = "8d420deb9e59937c0113f75fb419baa5";

            try
            {
                var client = new TwilioRestClient(accountSid, authToken);

                client.SendSmsMessage("(980) 365-8354", phoneTo, smsString);

                return true;
            }

            catch (Exception)
            {
                return false;
            }

        }


    }
}
